﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using BaseData.Exts;
using BaseLib.Helper;

namespace BaseData.Lib
{
    public class RepositoryBase<TEntity> : IRepository<TEntity> where TEntity : class
    {
        #region - 变量 -

        private ContextExt dbContext;
        public ContextExt DBContext
        {
            get { return this.dbContext; }
        }

        protected DbSet<TEntity> dbSet;

        #endregion

        #region - 构造函数 -

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbContext">操作数据库的上下文对象</param>
        public RepositoryBase(ContextExt dbContext)
        {
            this.dbContext = dbContext;
            this.dbSet = this.dbContext.Set<TEntity>();
        }
        public RepositoryBase() : this(DbContextFactory.GetDbContext()) { }

        #endregion

        #region - 获取处理过的 PageIndex -

        private int GetPageIndex(int pageIndex)
        {
            return pageIndex = (pageIndex <= 0 ? 1 : pageIndex);
        }

        #endregion

        #region IRepository<TEntity> 成员

        public bool IsExist(Expression<Func<TEntity, bool>> predicate)
        {
            return this.dbSet.Any(predicate);
        }

        #region - 获取所有的记录 -

        public virtual IQueryable<TEntity> All()
        {
            return this.dbSet;
        }

        public virtual PagerList<TEntity> All(int pageIndex, int pageSize, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy)
        {
            return orderBy(this.dbSet).ToPagerList(this.GetPageIndex(pageIndex), pageSize);
        }

        public virtual PagerList<TEntity> All(Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy, int pageIndex, int pageSize)
        {
            return orderBy(this.dbSet).ToPagerList(this.GetPageIndex(pageIndex), pageSize);
        }

        #endregion

        #region - 获取分页数据 -

        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="pageIndex">要访问的页</param>
        /// <param name="pageSize">页容量</param>
        /// <param name="where">条件</param>
        /// <param name="orderBy">排序</param>
        /// <param name="includeProperties">贪婪加载的成员</param>
        /// <returns></returns>
        public virtual IQueryable<TEntity> GetList(Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy, int pageIndex, int pageSize, Expression<Func<TEntity, bool>> where = null, string includeProperties = "")
        {
            foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                this.dbSet.Include(includeProperty);
            return @where != null
                ? orderBy(this.dbSet.Where(@where)).Skip((this.GetPageIndex(pageIndex) - 1) * pageSize).Take(pageSize)
                : orderBy(this.dbSet).Skip((this.GetPageIndex(pageIndex) - 1) * pageSize).Take(pageSize);
        }

        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="pageIndex">要访问的页</param>
        /// <param name="pageSize">页容量</param>
        /// <param name="where">条件</param>
        /// <param name="orderBy">排序</param>
        /// <returns></returns>
        public virtual PagerList<TEntity> GetList(int pageIndex, int pageSize, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy, Expression<Func<TEntity, bool>> where = null)
        {
            return @where != null
                ? orderBy(this.dbSet.Where(@where)).ToPagerList(this.GetPageIndex(pageIndex), pageSize)
                : orderBy(this.dbSet).ToPagerList(this.GetPageIndex(pageIndex), pageSize);
        }

        #endregion

        #region - 获取列表数据 -

        /// <summary>
        /// 获取列表数据
        /// </summary>
        /// <param name="where">条件</param>
        /// <param name="orderBy">排序</param>
        /// <returns></returns>
        public IQueryable<TEntity> GetList(Expression<Func<TEntity, bool>> where, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null)
        {
            return (orderBy != null) ? orderBy(this.dbSet.Where(where)) : this.dbSet.Where(where);
        }

        #endregion

        #region - 获取指定ID的记录--如果没有查询到数据，返回null -

        /// <summary>
        /// 获取指定ID的记录--如果没有查询到数据，返回null
        /// </summary>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public virtual TEntity Find(params object[] keyValues)
        {
            return this.dbSet.Find(keyValues);
        }

        #endregion

        #region - 获取单个记录--如果没有查询到数据，返回null -

        /// <summary>
        /// 获取单个记录--如果没有查询到数据，返回null
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns></returns>
        public virtual TEntity Find(Expression<Func<TEntity, bool>> where)
        {
            return this.dbSet.Where(where).FirstOrDefault();
        }

        #endregion

        #region - 插入 -

        /// <summary>
        /// 插入
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public TEntity Insert(TEntity entity)
        {
            return this.dbSet.Add(entity);
        }

        /// <summary>
        /// 插入
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public TEntity InsertBySave(TEntity entity)
        {
            var model = this.dbSet.Add(entity);
            this.Save();
            return model;
        }

        #endregion

        #region - 删除 -

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public TEntity Delete(params object[] keyValues)
        {
            var model = dbSet.Find(keyValues);
            return this.Delete(model);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public TEntity Delete(TEntity entity)
        {
            //if (this.dbContext.Entry(entity).State == EntityState.Detached)
            //{
            //	dbSet.Attach(entity);
            //}
            return dbSet.Remove(entity);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public TEntity DeleteBySave(params object[] keyValues)
        {
            return this.DeleteBySave(this.Delete(keyValues));
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public TEntity DeleteBySave(TEntity entity)
        {
            var model = this.Delete(entity);
            this.Save();
            return model;
        }

        public void Delete(IEnumerable<TEntity> entity)
        {
            foreach (var item in entity)
            {
                this.Delete(item);
            }
        }

        #endregion

        #region - 更新数据库 -

        /// <summary>
        /// 更新数据库
        /// </summary>
        /// <returns></returns>
        public int Save()
        {
            return this.dbContext.SaveChanges();
        }
        #endregion

        #endregion
    }
}
